/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package thread;

import DLL.CommonMethods;
import DLL.ReceivedData;
import DLL.SendFunction;
import DLL.WriteLog;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.sql.Time;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Random;
import javax.swing.JLabel;

/**
 *
 * @author PyyPyLyn
 */
public class Download_Core extends Thread{
    
    
//    JLabel lbGoiTin;
    
    List<byte[]> arraybytes;
    String chunkname;
    InetAddress add;
    List<Thread> threads;
    
    public Download_Core(String cn, InetAddress a, List<Thread> threadlist) {
        chunkname = cn;
        add = a;
        threads = threadlist;        
    }

    
    public void run() {
        
        
        DatagramSocket dl_Socket = null;
        int countthread = threads.size();
        int porta = 5000;
        List<ReceivedData> redata = new ArrayList<ReceivedData>();
        
        DatagramSocket socket_requestdownload;        
        boolean result = false;
        arraybytes = new ArrayList<byte[]>(); 
       
        try
        {      
            dl_Socket = new DatagramSocket(); 
            socket_requestdownload = new DatagramSocket();
            result = SendFunction.SendRequestDownload(socket_requestdownload, add, chunkname, dl_Socket.getLocalPort());
            dl_Socket.setSoTimeout(2000);
        }
        catch(Exception ex)
        {
            
        }         

//            if (result == true)
//            {
//                //JOptionPane.showMessageDialog(null, "Port download da mo!");
//                lbGoiTin.setText(""+dl_Socket.getLocalPort());
//            } 


        int sizedata = 0;
        int a = 0;

        byte[] response = "4".getBytes();
        DatagramPacket rs_Pkt = new DatagramPacket(response, response.length, add,4449);
        DatagramSocket rs_Socket = null;
        try
        {
            rs_Socket = new DatagramSocket();
        }
        catch (Exception ex)
        {
            
        }

        while(true)
        { 
            byte[] packet = new byte[1024];
            DatagramPacket packet_Data;
            try
            {        
                packet_Data = new DatagramPacket(packet, packet.length);
                dl_Socket.receive(packet_Data);                    
                
                a++;
                if(packet_Data.getData()[0] != 0)
                {
                    if(a==532)
                    { 
                        arraybytes.add(packet);
                    }
                    else
                    {   
                        arraybytes.add(packet);
                    }
//                        lbGoiTin.setText(""+a);  
                    try
                    {
                        rs_Socket.send(rs_Pkt);
                    }
                    catch(Exception ex)                           
                    {
                        
                    }
                }
                else
                {
                    break;
                }
            }
            catch(Exception ex)
            {           
                int count = arraybytes.size();
                if(count > 0)
                {
                    for(int c = 0; c < count; c++)
                    {
                        byte[] vData = (byte[]) arraybytes.get(c);
                        byte flags = vData[0];

                        byte[] headerlength = Arrays.copyOfRange(vData, 1, 3);
                        short valueHeaderlength = ByteBuffer.wrap(headerlength).order(ByteOrder.LITTLE_ENDIAN).getShort();
                        //String Header
                        byte[] header = Arrays.copyOfRange(vData, 17, 17+valueHeaderlength);
                        String valueHeader = new String(header);
                        String fileName = valueHeader;
                        if(fileName.equals(chunkname))
                        {
                            //Short packet length
                            byte[] packets = Arrays.copyOfRange(vData, 3, 5);
                            short valuePackets = ByteBuffer.wrap(packets).order(ByteOrder.LITTLE_ENDIAN).getShort();
                            //Integer CheckSum
                            byte[] checksum = Arrays.copyOfRange(vData, 5, 9);
                            int valueChecksum = ((checksum[0] & 0xFF) << 24) | ((checksum[1] & 0xFF) << 16)
                                   | ((checksum[2] & 0xFF) << 8) | (checksum[3] & 0xFF);
                            //Integer Sequence
                            byte[] sequence = Arrays.copyOfRange(vData, 9, 13);
                            int valuesequence = ((sequence[0] & 0xFF) << 24) | ((sequence[1] & 0xFF) << 16)
                                    | ((sequence[2] & 0xFF) << 8) | (sequence[3] & 0xFF);
                            //Integer Acknowledge
                            byte[] acknowledge = Arrays.copyOfRange(vData, 13, 17);
                            int valueacknowledge = ((acknowledge[0] & 0xFF) << 24) | ((acknowledge[1] & 0xFF) << 16)
                                    | ((acknowledge[2] & 0xFF) << 8) | (acknowledge[3] & 0xFF);

                            //ByteData
                            byte[] data = Arrays.copyOfRange(vData, 17+valueHeaderlength, 17+valueHeaderlength+valuePackets);
                            int Ischecksum = (int)CommonMethods.calculateChecksum(data);
                            if(true)
                            {
                                ReceivedData rdata = new ReceivedData(data, valuesequence, valueacknowledge);
                                redata.add(rdata);                       
                                sizedata+=data.length;

                            }
                        }
                    }
                    redata = CommonMethods.SortReceivedData(redata);
                    byte[] endByte = new byte[sizedata];
                    int abc = 0;
                    for(int c=0;c<redata.size();c++)
                    {
                        for(int e = 0; e<redata.get(c).data.length; e++)
                        {
                            if(abc == 985)
                            {
                                int f = 0;
                                f = 1;
                            }
                            endByte[abc] = redata.get(c).data[e];
                            abc++;                    
                        }
                        //endByte = Arrays.copyOfRange(redata.get(c).data, abc, abc+redata.get(c).data.length);

                    }
                    CommonMethods.ConvertByteArrayIntoFile(endByte,chunkname);
                    try
                    {
                        WriteLog.WriteLog(chunkname, false, add.getHostAddress());
                    }
                    catch(Exception ax)
                    {
                    }
                }
                rs_Socket.close();                    
                break;
            }                
        }
        
    }
    
    
    
}
